<template>
  <div class="room-container">
    <!-- 头部信息 -->
    <div class="room-header">
      <h2>房间号: {{ roomId }}</h2>
      <p>用户名: {{ username }} | 角色: {{ isBroadcaster ? '主播' : '观众' }}</p>
      <button
          v-if="isBroadcaster"
          @click="toggleSharing"
          :class="{ 'sharing-active': isSharing }"
      >
        {{ isSharing ? '停止共享' : '开始共享' }}
      </button>
    </div>

    <!-- 视频区域 -->
    <div class="video-area">
      <!-- 本地视频（主播） -->
      <div v-if="isBroadcaster" class="video-wrapper">
        <h3>我的屏幕</h3>
        <video ref="localVideo" autoplay muted playsinline></video>
      </div>

      <!-- 远程视频 -->
      <div v-for="(stream, username) in remoteStreams" :key="username" class="video-wrapper">
        <h3>{{ username }}的屏幕</h3>
        <video :ref="`remoteVideo-${username}`" autoplay playsinline></video>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      roomId: this.$route.params.roomId || 'default-room',
      username: localStorage.getItem('username') || 'user_' + Math.random().toString(36).substr(2, 5),
      isBroadcaster: this.$route.query.role === 'broadcaster',
      isSharing: false,
      socket: null,
      peerConnections: {},
      localStream: null,
      remoteStreams: {}
    }
  },

  created() {
    if (!localStorage.getItem('username')) {
      localStorage.setItem('username', this.username)
    }
    this.initSocket()
  },

  beforeDestroy() {
    this.cleanup()
  },

  methods: {
    initSocket() {
      const wsProtocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://'
      //this.socket = new WebSocket(`${wsProtocol}${window.location.host}/ws`)
      this.socket = new WebSocket("ws://localhost:8080/ws")

      this.socket.onopen = () => {
        console.log('WebSocket connected')
        this.sendMessage({
          type: 'join',
          roomId: this.roomId,
          username: this.username,
          role: this.isBroadcaster ? 'broadcaster' : 'viewer'
        })
      }

      this.socket.onmessage = (event) => {
        const msg = JSON.parse(event.data)
        this.handleSocketMessage(msg)
      }

      this.socket.onclose = () => {
        console.log('WebSocket disconnected')
      }
    },

    async toggleSharing() {
      if (this.isSharing) {
        await this.stopSharing()
      } else {
        await this.startSharing()
      }
      this.isSharing = !this.isSharing
    },

    async startSharing() {
      try {
        this.localStream = await navigator.mediaDevices.getDisplayMedia({
          video: {width: 1280, height: 720},
          audio: true
        })

        this.$refs.localVideo.srcObject = this.localStream
        this.localStream.getVideoTracks()[0].onended = this.stopSharing

        // 通知所有观众
        this.broadcastToRoom({
          type: 'broadcast-started',
          username: this.username
        })

      } catch (error) {
        console.error('屏幕共享失败:', error)
      }
    },

    async stopSharing() {
      if (this.localStream) {
        this.localStream.getTracks().forEach(track => track.stop())
        this.localStream = null
        this.$refs.localVideo.srcObject = null
      }

      this.broadcastToRoom({
        type: 'broadcast-ended',
        username: this.username
      })
    },

    handleSocketMessage(msg) {
      switch (msg.type) {
        case 'new-user':
          if (msg.role === 'viewer' && !this.isBroadcaster) {
            this.createPeerConnection(msg.username)
          }
          break

        case 'offer':
          this.handleOffer(msg)
          break

        case 'answer':
          this.handleAnswer(msg)
          break

        case 'candidate':
          this.handleCandidate(msg)
          break

        case 'user-left':
          this.handleUserLeft(msg.username)
          break

        case 'broadcast-started':
          if (!this.isBroadcaster) {
            this.createPeerConnection(msg.username)
          }
          break

        case 'broadcast-ended':
          this.handleUserLeft(msg.username)
          break
      }
    },

    createPeerConnection(targetUsername) {
      const pc = new RTCPeerConnection({
        iceServers: [{urls: 'stun:stun.l.google.com:19302'}]
      })

      this.peerConnections[targetUsername] = pc

      pc.onicecandidate = (event) => {
        if (event.candidate) {
          this.sendMessage({
            type: 'candidate',
            targetUsername: targetUsername,
            candidate: event.candidate
          })
        }
      }

      pc.ontrack = (event) => {
        this.$set(this.remoteStreams, targetUsername, event.streams[0])
        this.$nextTick(() => {
          const videoRef = this.$refs[`remoteVideo-${targetUsername}`]
          if (videoRef && videoRef[0]) {
            videoRef[0].srcObject = event.streams[0]
          }
        })
      }

      if (this.isBroadcaster && this.localStream) {
        this.localStream.getTracks().forEach(track => {
          pc.addTrack(track, this.localStream)
        })
        this.createOffer(targetUsername)
      }
    },

    async createOffer(targetUsername) {
      const pc = this.peerConnections[targetUsername]
      try {
        const offer = await pc.createOffer()
        await pc.setLocalDescription(offer)

        this.sendMessage({
          type: 'offer',
          targetUsername: targetUsername,
          sdp: offer
        })
      } catch (error) {
        console.error('创建Offer失败:', error)
      }
    },

    async handleOffer(msg) {
      const pc = this.createPeerConnection(msg.username)
      try {
        await pc.setRemoteDescription(new RTCSessionDescription(msg.sdp))
        const answer = await pc.createAnswer()
        await pc.setLocalDescription(answer)

        this.sendMessage({
          type: 'answer',
          targetUsername: msg.username,
          sdp: answer
        })
      } catch (error) {
        console.error('处理Offer失败:', error)
      }
    },

    async handleAnswer(msg) {
      const pc = this.peerConnections[msg.username]
      if (pc) {
        try {
          await pc.setRemoteDescription(new RTCSessionDescription(msg.sdp))
        } catch (error) {
          console.error('处理Answer失败:', error)
        }
      }
    },

    async handleCandidate(msg) {
      const pc = this.peerConnections[msg.username]
      if (pc && msg.candidate) {
        try {
          await pc.addIceCandidate(new RTCIceCandidate(msg.candidate))
        } catch (error) {
          console.error('添加ICE Candidate失败:', error)
        }
      }
    },

    handleUserLeft(username) {
      if (this.peerConnections[username]) {
        this.peerConnections[username].close()
        delete this.peerConnections[username]
        this.$delete(this.remoteStreams, username)
      }
    },

    sendMessage(message) {
      if (this.socket && this.socket.readyState === WebSocket.OPEN) {
        this.socket.send(JSON.stringify({
          ...message,
          roomId: this.roomId,
          username: this.username
        }))
      }
    },

    broadcastToRoom(message) {
      this.sendMessage({
        ...message,
        broadcast: true
      })
    },

    cleanup() {
      // 关闭所有PeerConnection
      Object.values(this.peerConnections).forEach(pc => pc.close())
      this.peerConnections = {}

      // 停止本地流
      if (this.localStream) {
        this.localStream.getTracks().forEach(track => track.stop())
        this.localStream = null
      }

      // 关闭Socket连接
      if (this.socket) {
        this.sendMessage({type: 'leave'})
        this.socket.close()
      }
    }
  }
}
</script>

<style scoped>
.room-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

.room-header {
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
}

.video-area {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 20px;
}

.video-wrapper {
  background: #f5f5f5;
  border-radius: 8px;
  overflow: hidden;
}

video {
  width: 100%;
  background: #000;
}

button {
  padding: 8px 16px;
  background: #42b983;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background: #369f6b;
}

button.sharing-active {
  background: #ff5252;
}

button.sharing-active:hover {
  background: #ff0000;
}
</style>
